#include <string.h>

#include "galaxian.h"
#include "spaceship.h"
#include <SDL/SDL.h>
#include <SDL/SDL_audio.h>
//#include "sounds.c"
#include "font.h"
//variaveis de depuracao
int debugMode = 0;
int debugShowAnotherFrame=0;

int paused = 0;
int survival = 0;
int playing = 0;
int restart = 0;
int level = 0;
int hi_score=0;
int shoots = 1;

const int initialEnemyLines = 1;
const int initialEnemyRows = 1;

int enemyLines = initialEnemyLines;
int enemyRows = initialEnemyRows;

const int maxEnemyLines = 2;
const int maxEnemyRows = 3;
const int STARS = 200;


struct Stars star[STARS];

int sentido = 1; //Sentido 1 vai para a direita, -1 para a esquerda
const double initialEnemySpeed = 0.04;
double enemySpeed = initialEnemySpeed;
double enemySpeedy = (WIDTH)/400;
const double starSpeed = (WIDTH/70);
int period = 400;//qto menor maior o numero de ataques
int randomAttack;
int specialAttack;
int randomSpAttack;

//Vetores de identificadores de texturas
GLint tex_enemy[4];
GLint tex_collision[nFramesExp];
GLint tex_player;
GLint tex_flag;
GLint tex_initial;
GLint tex_congratulations;
GLint tex_game_over;

//contadores de movimento de inimigos
int enemyFrame = 0;
int frame = 0;

SpaceShip *nave;
Enemy *inimigo[maxEnemyLines][maxEnemyRows];


/*
 Carrega texturas
 */
void loadTextures(){

    tex_enemy[0] = SOIL_load_OGL_texture("imgs/enemy01.png", SOIL_LOAD_AUTO,
		SOIL_CREATE_NEW_ID, SOIL_FLAG_MULTIPLY_ALPHA);

    tex_enemy[1] = SOIL_load_OGL_texture("imgs/enemy02.png", SOIL_LOAD_AUTO,
		SOIL_CREATE_NEW_ID, SOIL_FLAG_MULTIPLY_ALPHA);

    tex_enemy[2] = SOIL_load_OGL_texture("imgs/enemy03.png", SOIL_LOAD_AUTO,
		SOIL_CREATE_NEW_ID, SOIL_FLAG_MULTIPLY_ALPHA);

    tex_enemy[3] = SOIL_load_OGL_texture("imgs/enemy04.png", SOIL_LOAD_AUTO,
		SOIL_CREATE_NEW_ID, SOIL_FLAG_MULTIPLY_ALPHA);


    tex_player = SOIL_load_OGL_texture("imgs/player01.png", SOIL_LOAD_AUTO,
		SOIL_CREATE_NEW_ID, SOIL_FLAG_MULTIPLY_ALPHA);


    tex_collision[0] = SOIL_load_OGL_texture("imgs/explosion01.png",
		SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MULTIPLY_ALPHA);

    tex_collision[1] = SOIL_load_OGL_texture("imgs/explosion02.png",
		SOIL_LOAD_AUTO,	SOIL_CREATE_NEW_ID, SOIL_FLAG_MULTIPLY_ALPHA);

    tex_collision[2] = SOIL_load_OGL_texture("imgs/explosion03.png",
		SOIL_LOAD_AUTO,	SOIL_CREATE_NEW_ID, SOIL_FLAG_MULTIPLY_ALPHA);

    tex_collision[3] = SOIL_load_OGL_texture("imgs/explosion04.png",
		SOIL_LOAD_AUTO,	SOIL_CREATE_NEW_ID, SOIL_FLAG_MULTIPLY_ALPHA);

    tex_collision[4] = SOIL_load_OGL_texture("imgs/explosion05.png",
		SOIL_LOAD_AUTO,	SOIL_CREATE_NEW_ID, SOIL_FLAG_MULTIPLY_ALPHA);

    tex_collision[5] = SOIL_load_OGL_texture("imgs/explosion06.png",
		SOIL_LOAD_AUTO,	SOIL_CREATE_NEW_ID, SOIL_FLAG_MULTIPLY_ALPHA);

    tex_collision[6] = SOIL_load_OGL_texture("imgs/explosion07.png",
		SOIL_LOAD_AUTO,	SOIL_CREATE_NEW_ID, SOIL_FLAG_MULTIPLY_ALPHA);


    tex_flag = SOIL_load_OGL_texture("imgs/flag.png",
		SOIL_LOAD_AUTO,	SOIL_CREATE_NEW_ID, SOIL_FLAG_MULTIPLY_ALPHA);

    tex_initial = SOIL_load_OGL_texture("imgs/galaxian_init.png",
		SOIL_LOAD_AUTO,	SOIL_CREATE_NEW_ID, SOIL_FLAG_MULTIPLY_ALPHA);

    tex_congratulations= SOIL_load_OGL_texture("imgs/congratulations.png",
		SOIL_LOAD_AUTO,	SOIL_CREATE_NEW_ID, SOIL_FLAG_MULTIPLY_ALPHA);

    tex_game_over= SOIL_load_OGL_texture("imgs/gameover.png",
		SOIL_LOAD_AUTO,	SOIL_CREATE_NEW_ID, SOIL_FLAG_MULTIPLY_ALPHA);

}

void init(void){
    glMatrixMode(GL_PROJECTION);

    glClearColor(1.0f, 1.0f, 1.0f, 0.0f);

    glOrtho(0.0,WIDTH,0.0,HEIGHT,0.0,1.0);

    loadTextures();

    initStars();

    initGame();
    
    paused = 1;
/*
    //extern void mixaudio(void *unused, Uint8 *stream, int len);
    if (SDL_Init(SDL_INIT_AUDIO) != 0) {
    fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
    }

    SDL_AudioSpec fmt;

    /* Set 16-bit stereo audio at 22Khz */
  /*  fmt.freq = 22050;
    fmt.format = AUDIO_S16;
    fmt.channels = 2;
    fmt.samples = 512;        /* A good value for games */
    /*fmt.callback = mixaudio;
    fmt.userdata = NULL;
if ( SDL_OpenAudio(&fmt, NULL) < 0 ) {
        fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError());
        exit(1);
    }
    SDL_PauseAudio(0); */
}

int  initGame(){
    level=1;
    shoots = 1;
    enemyLines=initialEnemyLines;
    enemyRows=initialEnemyRows;
    enemySpeed = initialEnemySpeed;
    enemySpeedy = WIDTH/400;
    enemyFrame = 0;
    frame = 0;
    nave = new SpaceShip(tex_player);
    enemyGrid(enemyLines, enemyRows);
    restart = 0;
    return 0;
}

int newLevel(){
        enemySpeed = initialEnemySpeed*((level/2)+1);
        enemySpeedy = (WIDTH/400)*((level/2)+1);
        deleteEnemyGrid(maxEnemyLines, maxEnemyRows);
        enemyFrame = 0;
        frame = 0;
        if (++enemyRows>maxEnemyRows){
            enemyRows=maxEnemyRows;
        }
         if (++enemyLines>maxEnemyLines){
            enemyLines=maxEnemyLines;
        }
        enemyGrid(enemyLines, enemyRows);
        return ++level;
}

//atualiza a tela
void display(void){
    glClear(GL_COLOR_BUFFER_BIT);

    if(playing==0){
        drawInitialScreen();
    }

    if(playing==1){
        drawScreenPaper();
        drawSpaceship();
        drawEnemies(enemyLines, enemyRows,tex_enemy[enemyFrame]);
    }

    if(restart!=0){
        delete nave;
        deleteEnemyGrid(maxEnemyLines, maxEnemyRows);
        level = 1;
        initGame() ;
    }

    if(nave->gameOver){
        if(nave->lifes >= 1) {
            paused=1;
            playing=2;
            survival=1;
            drawEndScreenWinner();//Voce venceu
        }
       if(nave->lifes < 1 && nave->explosion==false) {//You looooooose, continues? 8, 7 ... Final round...
       if(!survival)drawGameOver();
       paused=1;
       glutSwapBuffers();
       usleep(4000000);
       initGame();
       playing=0;
       survival=0;
       }
    }
    glutSwapBuffers();

    
}


void redesenha(int time){
    display();
    glutTimerFunc(33,redesenha,1);
}

//usado para controlar as acoes de acordo com o tempo
void timer(int time){

    if(!debugMode || debugShowAnotherFrame>0){
        frame=(frame+1)%12;

        if(!paused || debugMode){

            nave->move();
            stageLogic(enemyLines, enemyRows);//a fim de imprimir movimento especial e os tiros e a colisao causada por eles
            if(frame%6==0){//A nave move a cada 6 frames para dar a sensaçao de um movimento travado CLASSIC!
              
              if(debugShowAnotherFrame>0){
                  debugShowAnotherFrame=0;}
              moveEnemies();
              enemyFrame=(enemyFrame+1)%3; //Variavel Global Modifica a frame atual dos inimigos
            }
        }
        if(frame%4==0) {
            reloadStars();

        }
    }else{
        if(debugShowAnotherFrame==0){
            debugVariables();
            debugShowAnotherFrame=-1;
            
        }
    }
    glutTimerFunc(66,timer,1);
}


void idle(){
    if(testEnemyAlive (enemyLines, enemyRows) && playing==1){
        usleep(100000);
        newLevel();
        if(level==6)nave->gameOver=1;
    }

}

void initStars(){

	for (int i=0; i < STARS; i++){
		star[i].x =(double)(rand()% ( ( (int)WIDTH*10 +10)))  /10;
                star[i].y =(double)(rand()% ( ( (int)HEIGHT*10 + 10 ))) /10;
                star[i].draw = 1;
                switch(rand()%4){
                    case 0:
                        star[i].r = white[0];
                        star[i].g = white[1];
                        star[i].b = white[2];
                        break;
                    case 1:
                        star[i].r = yellow[0];
                        star[i].g = yellow[1];
                        star[i].b = yellow[2];
                        break;
                    case 2:
                        star[i].r = red[0];
                        star[i].g = red[1];
                        star[i].b = red[2];
                        break;
                    case 3:
                        star[i].r = blue[0];
                        star[i].g = blue[1];
                        star[i].b = blue[2];
                        break;
                    default:
                        star[i].r = 0.0;
                        star[i].g = 0.0;
                        star[i].b = 0.0;
                        break;
                }

        }
}


//Move as estrelas para baixo, caso acabe a tela ele move estrela para o topo
void reloadStars(){

	for (int i=0; i < STARS; i++){
                if((star[i].y -=starSpeed)<0)star[i].y=HEIGHT;
                star[i].draw = rand()%2;
        }
}

void drawInitialScreen(){

    glEnable(GL_TEXTURE_2D);
        glEnable(GL_ALPHA_TEST);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
        glBindTexture(GL_TEXTURE_2D, tex_initial);
        glBegin(GL_QUADS);
        glTexCoord2d(0.0, 0.0);
        glVertex2f(0.0, 0.0);
        glColor3f(1.0, 1.0, 1.0);
        glTexCoord2d(1.0, 0.0);
        glVertex2f(WIDTH, 0.0);
        glTexCoord2d(1.0, 1.0);
        glVertex2f(WIDTH,HEIGHT);
        glColor3f(1.0,1.0,1.0);
        glTexCoord2d(0.0, 1.0);
        glVertex2f(0.0, HEIGHT);

        glEnd();
        glDisable(GL_TEXTURE_2D);
        glDisable(GL_BLEND);
        glClear(GL_COLOR);



    char controles[30];
    char creditos[30];
    char score[20];


    hi_score=(hi_score > nave->score?hi_score : nave->score);
    sprintf(score,"High Score: %d", hi_score);
    glClear(GL_COLOR);
    glColor3f(1.0, 0.0, 0.0);
    SetFont(GLUT_BITMAP_HELVETICA_18);
    DrawFont(score, WIDTH/2 - 0.7, HEIGHT-0.2);


    sprintf(controles,"Pressione Enter ou S para Iniciar Jogo");
    glClear(GL_COLOR);
    glColor3f(1.0, 1.0, 1.0);
    SetFont(GLUT_BITMAP_HELVETICA_18);
    DrawFont(controles, WIDTH/2 -1 , HEIGHT-3.2);
    sprintf(controles,"Pressione R para Reiniciar Jogo");
    DrawFont(controles, WIDTH/2 -1 , HEIGHT-3.4);
    sprintf(controles,"Pressione D para modo de Depuração");
    DrawFont(controles, WIDTH/2 -1 , HEIGHT-3.6);
    sprintf(controles,"Pressione P para Pausar Jogo");
    DrawFont(controles, WIDTH/2 -1 , HEIGHT-3.8);
    sprintf(controles,"Esq ou Q sai do Jogo");
    DrawFont(controles, WIDTH/2 -1 , HEIGHT-4.0);
    SetFont(GLUT_BITMAP_8_BY_13);
    glClear(GL_COLOR);
    glColor3f(1.0, 1.0, 1.0);
    sprintf(creditos,"Creditos: Bruno Samuel Leal Rocha");
    DrawFont(creditos, 0, 0);
    glClear(GL_COLOR);
}

void drawEndScreenWinner(){

    glEnable(GL_TEXTURE_2D);
        glEnable(GL_ALPHA_TEST);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
        glBindTexture(GL_TEXTURE_2D, tex_congratulations);
        glBegin(GL_QUADS);
        glColor3f(1.0, 1.0, 1.0);
        glTexCoord2d(0.0, 0.0);
        glVertex2f(0.0, 0.0);   
        glTexCoord2d(1.0, 0.0);
        glVertex2f(WIDTH, 0.0);
        glTexCoord2d(1.0, 1.0);
        glVertex2f(WIDTH,HEIGHT);
        glColor3f(1.0,1.0,1.0);
        glTexCoord2d(0.0, 1.0);
        glVertex2f(0.0, HEIGHT);

        glEnd();
        glDisable(GL_TEXTURE_2D);
        glDisable(GL_BLEND);
        glClear(GL_COLOR);


    char final[60];
    char controles[80];
    char creditos[60];
    char score[20];

     sprintf(score,"Score: %d", nave->score);
    glColor3f(1.0, 0.0, 0.0);
    SetFont(GLUT_BITMAP_HELVETICA_18);
    DrawFont(score, 0.2, HEIGHT-0.2);

    hi_score=(hi_score > nave->score?hi_score : nave->score);
    sprintf(score,"High Score: %d", hi_score);
    glClear(GL_COLOR);
    glColor3f(1.0, 0.0, 0.0);
    SetFont(GLUT_BITMAP_HELVETICA_18);
    DrawFont(score, WIDTH/2 - 0.7, HEIGHT-0.2);

    sprintf(final,"Parabens! Voce venceu!");
    glClear(GL_COLOR);
    glColor3f(1.2, 1.2, 0.6);
    SetFont(GLUT_BITMAP_TIMES_ROMAN_24);
    DrawFont(final, WIDTH/2 -2.5 , HEIGHT-2.0);
    sprintf(final,"A Terra pode mais uma vez descansar em Paz!");
    DrawFont(final, WIDTH/2 -2.5 , HEIGHT-2.4);
    sprintf(final,"Mas e voce?... Ate quando voce aguenta?");
    DrawFont(final, WIDTH/2 -2.5 , HEIGHT-2.8);


    glClear(GL_COLOR);
    glColor3f(1.0, 1.0, 1.0);
    SetFont(GLUT_BITMAP_HELVETICA_18);
    sprintf(controles,"Pressione C para continuar jogando em Survival Mode!");
    DrawFont(controles, WIDTH/2 -2.5 , HEIGHT-4.2);
    glClear(GL_COLOR);
    glColor3f(1.0, 1.0, 0.0);
    SetFont(GLUT_BITMAP_HELVETICA_12);
    sprintf(controles,"Esq ou Q sai do Jogo");
    DrawFont(controles, WIDTH/2 -1 , HEIGHT-4.5);


    SetFont(GLUT_BITMAP_8_BY_13);
    glClear(GL_COLOR);
    glColor3f(1.0, 1.0, 1.0);
    sprintf(creditos,"Creditos: Bruno Samuel Leal Rocha");
    DrawFont(creditos, 0, 0);
    glClear(GL_COLOR);
}


void drawGameOver(){

    glEnable(GL_TEXTURE_2D);
        glEnable(GL_ALPHA_TEST);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
        glBindTexture(GL_TEXTURE_2D, tex_game_over);
        glBegin(GL_QUADS);
        glColor3f(1.0, 1.0, 1.0);
        glTexCoord2d(0.0, 0.0);
        glVertex2f(0.0, 0.0);
        glTexCoord2d(1.0, 0.0);
        glVertex2f(WIDTH, 0.0);
        glTexCoord2d(1.0, 1.0);
        glVertex2f(WIDTH,HEIGHT);
        glColor3f(1.0,1.0,1.0);
        glTexCoord2d(0.0, 1.0);
        glVertex2f(0.0, HEIGHT);
        glEnd();
        glDisable(GL_TEXTURE_2D);
        glDisable(GL_BLEND);
        glClear(GL_COLOR);



    char final[30];
    char creditos[30];
    char score[20];


    hi_score=(hi_score > nave->score?hi_score : nave->score);
    sprintf(score,"High Score: %d", hi_score);
    glClear(GL_COLOR);
    glColor3f(1.0, 0.0, 0.0);
    SetFont(GLUT_BITMAP_HELVETICA_18);
    DrawFont(score, WIDTH/2 - 0.7, HEIGHT-0.2);


    sprintf(final,"Voce falhou!");
    glClear(GL_COLOR);
    glColor3f(1.0, 0.9, 0.9);
    SetFont(GLUT_BITMAP_TIMES_ROMAN_24);
    DrawFont(final, WIDTH/2 -2.5 , HEIGHT-1.2);
    sprintf(final,"A Terra foi dominada!");
    DrawFont(final, WIDTH/2 -2.5 , HEIGHT-1.6);
    sprintf(final,"Os invasores alienigenas venceram");
    DrawFont(final, WIDTH/2 -2.5 , HEIGHT-2.0);
    glClear(GL_COLOR);
    glColor3f(1.0, 1.0, 1.0);
    SetFont(GLUT_BITMAP_8_BY_13);
    sprintf(creditos,"Creditos: Bruno Samuel Leal Rocha");
    DrawFont(creditos, 0, 0);
    glClear(GL_COLOR);
}

void drawScreenPaper(){

    glBegin(GL_QUADS);
    glColor3f(0.0,0.0,0.0);
    glVertex2f(0, HEIGHT);
    glVertex2f(WIDTH, HEIGHT);
    glColor3f(0.0,0.0,0.3);
    glVertex2f(WIDTH, 0);
    glVertex2f(0,  0);
    glEnd();

    glPointSize(2.0);
    glBegin(GL_POINTS);

    for (int i=0; i<STARS; i++)
	{
            if(star[i].draw){//efeito de ser desenhada ou nao
		glColor3f(star[i].r,star[i].g,star[i].b);
		glVertex2f(star[i].x, star[i].y);
            }
    }
    glEnd();
    double x = WIDTH-0.3;
    double y = 0.23;
    for (int i=1; i<level; i++)
	{
		drawOnScreen(tex_flag,white,x,y);
                x-=0.25;
    }
    x=0.3;
    for (int i=0; i < nave->lifes; i++)
	{
		drawOnScreen(tex_player,white,x,y);
                x+=0.4;
    }
    drawSpeedBar();
    hi_score=(hi_score > nave->score?hi_score : nave->score);
    char score[20];
    sprintf(score,"Score: %d", nave->score);
    glColor3f(1.0, 0.0, 0.0);
    SetFont(GLUT_BITMAP_HELVETICA_18);
    DrawFont(score, 0.2, HEIGHT-0.2);

    sprintf(score,"High Score: %d", hi_score);
    glColor3f(1.0, 0.0, 0.0);
    SetFont(GLUT_BITMAP_HELVETICA_18);
    DrawFont(score, WIDTH/2 - 0.7, HEIGHT-0.2);

}

int drawOnScreen(GLuint tex, const double *color, double x, double y ){

    glEnable(GL_TEXTURE_2D);
    glEnable(GL_ALPHA_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    glBindTexture(GL_TEXTURE_2D, tex);
    glBegin(GL_QUADS);
    glColor3f(color[0],color[1],color[2]);
    glTexCoord2d(0.0, 1.0);
    glVertex2f(x - ENEMYWIDTH/2, y - ENEMYHEIGHT/2);
    glTexCoord2d(0.0,  0.0);
    glVertex2f(x - ENEMYWIDTH/2, y + ENEMYHEIGHT/2);
    glTexCoord2d(1.0, 0.0);
    glVertex2f(x + ENEMYWIDTH/2, y + ENEMYHEIGHT/2);
    glTexCoord2d(1.0, 1.0);
    glVertex2f(x + ENEMYWIDTH/2, y - ENEMYHEIGHT/2);

    glEnd();
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);
    glClear(GL_COLOR);
    return 0;
}

int drawSpeedBar(){
    glBegin(GL_QUADS);
    glColor3f(1.0,0.3,0.3);
    glVertex2f( nave->speed*30 + WIDTH/2, 0.10);
    glVertex2f( nave->speed*30 + WIDTH/2, 0.02);

    glColor3f(0.0,0.0,0.0);
    glVertex2f(WIDTH/2,  0.02);
    glVertex2f(WIDTH/2, 0.10);
    glEnd();
    glClear(GL_COLOR);
    return 0;
}

/*
 Desenho da nave

 */

void drawSpaceship(){

 if(nave->explosion){
                nave->drawSpaceship(tex_collision[nave->expFrame/3]);
                nave->expFrame++;
               if(nave->expFrame/3>(nFramesExp-1)){
                   nave->explosion=false;
                   nave->expFrame=0;
                   nave->positionx = WIDTH/2;
                   nave->positiony = BOTTOM;
               }
    }else  nave->drawSpaceship(tex_player);

}

/*
 MOVIMENTO E COMPORTAMENTO DAS NAVES INIMIGAS
*/
void enemyGrid(double x, double y){
    double  unitWidth, unitHeight;
    double initialWidth, initialHeight;
    int points =0;
    initialWidth = (WIDTH/2) - ((y-1)/2)*(ENEMYWIDTH*1.45);
    initialHeight = (0.9*HEIGHT);


    int i , j;
    for(j=0; j<maxEnemyLines; j++){
        if(j==0){
                points = 100;
        }
        else if(j==1){
                points = 70;
        }
        else if(j==2){
                points = 50;
        }
        else {
                points = 30;
        }

        unitHeight = initialHeight - j*(ENEMYHEIGHT*1.10);

        for(i=0; i< maxEnemyRows; i++){   //percorre cada linha
            unitWidth = initialWidth + i*(ENEMYWIDTH*1.45);

           inimigo[j][i] =new Enemy(unitWidth,unitHeight, points);
           if(i>=y||j>=x)inimigo[j][i]->status=false;//desenha apenas os inimigos da fase atual
        }

    }

}

void deleteEnemyGrid(double x, double y){
    int i , j;
    for(j=0; j<x; j++){
        for(i=0; i< y; i++){   //percorre cada linha
           delete inimigo[j][i];
        }
    }
}

int testEnemyAlive(double x, double y){
    int i , j;
    for(j=0; j<x; j++){
        for(i=0; i< y; i++){   //percorre cada linha
            if(inimigo[j][i]->status==true||inimigo[j][i]->explosion==true) return 0;
        }
    } return 1;
}

int sideToMove(){
    int i,j;
    double posicao_x;
     for(j=0;j< enemyLines; j++){
        for(i=0; i< enemyRows; i++){
            posicao_x = inimigo[j][i]->getPositionx();
            
            if(posicao_x > 0.95*WIDTH && inimigo[j][i]->status==true){
                sentido = -1;
                return 0;
           }
            if(posicao_x < 0.05*WIDTH && inimigo[j][i]->status==true){
                sentido = 1;
                return 0;
            }
        }
    } return 0;



}

void moveEnemies(){
    sideToMove();
    int i,j;
     for(j=0;j< enemyLines; j++){
        for(i=0; i< enemyRows; i++){
            if(inimigo[j][i]->getStatus()){
               randomAttack += rand()%10;
               randomSpAttack += rand()%4;
               if(randomAttack>period && inimigo[j][i]->specialMove==false){//apenas inimigos normais atiram com o trytoshoot
                   inimigo[j][i]->TryToShoot();
                   randomAttack=0;
                }
               if(randomSpAttack>period){
                   inimigo[j][i]->TrySpecialMove(nave->getPositionx());                 
                   randomSpAttack=0;
                }
               inimigo[j][i]->move(enemySpeed*sentido);
            }
        }    
    }
}




int drawEnemies(int x, int y, GLint texture ){
 int i , j;
 double color[3];
    for(j=0;j<x; j++){
        if(j==0){
                color[0]=yellow[0];
                color[1]=yellow[1];
                color[2]=yellow[2];
        }
        else if(j==1){
                color[0]=red[0];
                color[1]=red[1];
                color[2]=red[2];
        }
        else if(j==2){
                color[0]=purple[0];
                color[1]=purple[1];
                color[2]=purple[2];
        }
        else {
                color[0]=blue[0];
                color[1]=blue[1];
                color[2]=blue[2];
        }
        
        for(i=0; i<y; i++){
            if(inimigo[j][i]->getStatus()){
                if(inimigo[j][i]->specialMove){
                  inimigo[j][i]->drawEnemy(tex_enemy[3], color);
                  inimigo[j][i]->drawEnemyShoots();
                }else
                  inimigo[j][i]->drawEnemy(texture, color);
                  inimigo[j][i]->drawEnemyShoots();
               }
               if(inimigo[j][i]->explosion){
                    inimigo[j][i]->drawEnemy(tex_collision[inimigo[j][i]->expFrame/3], white);
                    inimigo[j][i]->expFrame++;
                    if(inimigo[j][i]->expFrame/3>(nFramesExp-1)){
                       inimigo[j][i]->explosion=false;
                    }

               }
               if(inimigo[j][i]->getStatus()==false&&inimigo[j][i]->HasShoots()){
                    inimigo[j][i]->drawEnemyShoots();
               }
           
        }
    }return 0;
}

int stageLogic(int x, int y){
    int i , j;
    double distancia;
    for(j=0;j<x; j++){
        for(i=0; i<y; i++){
           inimigo[j][i]->moveShoots();
           inimigo[j][i]->drawEnemyShoots();
           if(inimigo[j][i]->status && inimigo[j][i]->specialMove==false){
                if(nave->CollisionTestShoots(inimigo[j][i]->getPositionx(),inimigo[j][i]->getPositiony())){
                    nave->score+=inimigo[j][i]->value;//atualiza score da nave
                    inimigo[j][i]->destroyed();
                    }
           }

            //verifica colisao com inimigo em movimento especial
            if(inimigo[j][i]->status && inimigo[j][i]->specialMove==true){

                distancia = sqrt(pow(inimigo[j][i]->specialMovex - nave->getPositionx(),2)
                       + pow(inimigo[j][i]->specialMovey - nave->getPositiony(),2));

                if(distancia < (nave->radius + inimigo[j][i]->radius)){
                      inimigo[j][i]->destroyed();
                      nave->destroyed();
                      
                }
            //verifica colisao de tiro com inimigo em movimento especial
                if(nave->CollisionTestShoots(inimigo[j][i]->specialMovex,inimigo[j][i]->specialMovey)){
                    nave->score+=(inimigo[j][i]->value)*2;
                    inimigo[j][i]->destroyed();
                }
           }
           //verifica colisao com inimigo voltando para a posicao
            if(inimigo[j][i]->status && inimigo[j][i]->returnToPosition){
                if(nave->CollisionTestShoots(inimigo[j][i]->getPositionx(),inimigo[j][i]->specialMovey)){
                    nave->score+=inimigo[j][i]->value;
                      inimigo[j][i]->destroyed();
                }
           }
           if(inimigo[j][i]->CollisionTestShoots(nave->getPositionx(),nave->getPositiony())){
                nave->destroyed();
           }
           if(inimigo[j][i]->specialMove && inimigo[j][i]->getStatus()){
                specialAttack += rand()%10;
               inimigo[j][i]->SpecialMove(enemySpeed, enemySpeedy,nave->getPositionx());
               if(specialAttack>(period/3)){
               inimigo[j][i]->TryToShoot();//Inimigo atira em modo especial
               specialAttack=0;
               }

            }
           
            if(inimigo[j][i]->returnToPosition){
               inimigo[j][i]->ReturnToPosition(enemySpeedy);
            }
           
        }
    } return 0;
}

int debugVariables(){
    int i,j,k;
    if(playing==0){
        printf("\n\nFavor Iniciar o Jogo antes de Entrar no modo de Depuracao");
        return 0;
    }
    printf("\n\nImpressao da Posicao das Naves inimigas e seus respectivos tiros, caso existam");
     for(j=0;j< enemyLines; j++){
        for(i=0; i< enemyRows; i++){
            if(inimigo[j][i]->getStatus()){
                printf("\n\nPosicao original no grid: linha=%d coluna=%d", j,i);
               if(inimigo[j][i]->specialMove==false){//apenas inimigos em posicao normal
                   printf("\nPosicao atual na tela x=%g y=%g",
                           inimigo[j][i]->positionx, inimigo[j][i]->positiony);
                }
               if(inimigo[j][i]->specialMove){
                   printf("\nInimigo em Movimento especial");
                   printf("\nPosicao atual na tela x=%g y=%g",
                           inimigo[j][i]->specialMovex, inimigo[j][i]->specialMovey);
                }
                if(inimigo[j][i]->returnToPosition){
                   printf("\nInimigo em Retornando para posicao original");
                }
                for(k=0; k<EnemyShoots; k++){
                    if(inimigo[j][i]->tiro[k]->status == true){
                        printf("\nTiro emitido pelo inimigo acima, na posicao x=%g y=%g",
                           inimigo[j][i]->tiro[k]->positionx, inimigo[j][i]->tiro[k]->positionx);

                   }
                }
            }
        }
    }
     printf("\n\n\nImpressao da Posicao do Heroi e seus respectivos tiros, caso existam");
               printf("\nPosicao atual na tela x=%g y=%g",
                           nave->positionx, nave->positiony);
               for(k=0; k<shoots; k++){
                    if(nave->tiro[k]->status == true){
                        printf("\nTiro emitido pelo Heroi, na posicao x=%g y=%g",
                           nave->tiro[k]->positionx, nave->tiro[k]->positionx);

                   }
                }
     printf("\n\n\nVariaveis do Sistema: ");
     printf("\nLevel atual = %d", level);
     printf("\nNumero de linhas no Grid de inimigos = %d", (enemyLines>maxEnemyLines?maxEnemyLines:enemyLines));
     printf("\nNumero de colunas no Grid de inimigos = %d", (enemyRows>maxEnemyRows?maxEnemyRows:enemyRows));
     printf("\nVelocidade dos Inimigos = %g", enemySpeed);

     return 0;
}

void teclado(unsigned char c, int x, int y){

    if(c == 's'||c == 13){
        playing=1;
        paused=0;
    }
    if(c == 'r')
        restart=1;


    if(c == 'p')
        paused=(paused+1)%2;


    if(c == 'd'){
       debugMode=(debugMode+1)%2;
       
       paused=0;
       if(debugMode){
           printf("\n Modo de Depuração \n");
           debugShowAnotherFrame=1;
           paused=1;
       }
    }
    if(c == 'n'){
       if(debugMode){
           ("\n Mostra proximo Frame \n");
           debugShowAnotherFrame=1;
               }
    }

     if(c == 'c'){
         if(nave->gameOver && nave->lifes>0){
             nave->gameOver=0;
            playing=1;
            paused=0;
        }
     }

    if(c == 27 ||c == 'q')
        exit(0);

}


// **************************************************
// Função chamada quando o mouse anda sobre a janele
// e NÃO HÁ botão pressionado
// **************************************************
//atualiza velocidade da nave e coloca a cria uma zona morta para o mouse
void moveMouse (int x, int y)
{
   double diferenca = x - glutGet(GLUT_WINDOW_WIDTH)/2;
	if(diferenca >= 40||diferenca <= (-40)) {
           	nave->setSpeed(diferenca/3000);
	}else nave->setSpeed(0);
}
// **************************************************
// Função chamada quando o mouse anda sobre a janele
// e HÁ botão pressionado
// **************************************************

void clicaMouse(int button, int state, int x, int y){

    switch (button)
    {

        case GLUT_LEFT_BUTTON:
                               if (state == GLUT_DOWN){//Ao pressionar o botao esquerdo a nave tenta atirar
                                   if(!paused) nave->TryToShoot(shoots);
                                   //PlaySound((char*)"sounds/t.wav");
                               }
                               break;

        case GLUT_RIGHT_BUTTON:
                               if (state == GLUT_DOWN){//Ao pressionar o botao direito o jogo entra em modo de depuracao
                                  paused=(paused+1)%2;
                               }
                               break;

        case GLUT_MIDDLE_BUTTON:
                               if (state == GLUT_DOWN){
                                    debugMode=(debugMode+1)%2;
                                           paused=0;
                                  if(debugMode){
                                      debugShowAnotherFrame=1;
                                      printf("\n Modo de Depuração \n");
                                      paused=0;
                                  }
                               }
                               break;

    }
}
